package com.yubest.customserializer.anno;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.Objects;

/**
 * @Author hweiyu
 * @Description
 * @Date 2021/9/29 11:51
 */
@Slf4j
public class EnumJsonSerializer extends JsonSerializer<Object> implements ContextualSerializer {

    /**
     * 额外添加的字段的后缀
     */
    @Getter
    private String suffix;

    @Getter
    private Class enumCls;

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (value instanceof TypeText) {
            TypeText tt = (TypeText) value;
            gen.writeObject(tt.getType());
            this.writeExtFieldValue(tt.getText(), gen);
        } else if (value != null) {
            gen.writeObject(value);
            /**
             * 1、指定的枚举类非空
             * 2、指定的枚举类实现了 @see com.yubest.customserializer.anno.TypeText
             */
            if (!Objects.equals(enumCls, Void.class)
                    && Objects.equals(enumCls.getSuperclass(), TypeText.class)) {
                TypeText typeText = (TypeText) enumCls.getEnumConstants()[0];
                this.writeExtFieldValue(typeText.getMap().get(value), gen);
            }
        }
    }

    /**
     * 添加额外字段
     * @param value
     * @param gen
     * @throws IOException
     */
    private void writeExtFieldValue(Object value, JsonGenerator gen) throws IOException {
        // 获取序列化字段名称
        String fieldName = gen.getOutputContext().getCurrentName();
        gen.writeFieldName(fieldName + suffix);
        gen.writeObject(value);
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        //获取对象属性上的自定义注解
        EnumSerializer enumSerializer = property.getAnnotation(EnumSerializer.class);
        if (null != enumSerializer) {
            try {
                this.suffix = enumSerializer.suffix();
                this.enumCls = enumSerializer.enumCls();
                return this;
            } catch (Exception e) {
                log.error("createContextual error", e);
            }
        }
        return prov.findValueSerializer(property.getType(), property);
    }
}
